import 'dart:convert';
import 'dart:io';

import 'package:base_plugin/base_plugin.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:dio/dio.dart';
import 'package:finance_app/src/http_service/http_common_service.dart';
import 'package:finance_app/src/http_service/http_statement_of_account_service.dart';
import 'package:open_file/open_file.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart' as pathProvider;

class FileUtils {
  static Future<File> saveFile(Response<dynamic> data, String fileType,
      {CancelToken cancelToken,
      Map<String, dynamic> params,
      ProgressCallback onReceiverProgress}) async {
    if (await PermissionManager().canWriteStorage()) {
      File pdfFile = File(await _getFilePathByUrl(data, fileType));
      // if (!pdfFile.existsSync() || pdfFile.lengthSync() == 0) {
      if (pdfFile.existsSync()) {
        await pdfFile.delete();
        print("deleted");
      }
      await pdfFile.create();

      await BaseConfig.httpBase.download(data.requestOptions.uri.toString(),
          pdfFile.path, params, cancelToken, onReceiverProgress);
      // }
      if (pdfFile.lengthSync() == 0) return null;
      return pdfFile;
    }
    return null;
  }

  static Future<File> getPdfFile(String type, int id,
      {CancelToken cancelToken, ProgressCallback onReceiverProgress}) async {
    if (await PermissionManager().canWriteStorage()) {
      File pdfFile = File(await getPdfFilePath(type, id));
      // if (!pdfFile.existsSync() || pdfFile.lengthSync() == 0) {
      if (pdfFile.existsSync()) {
        await pdfFile.delete();
      }
      await pdfFile.create();
      await HttpCommonService.downloadPDF(
          pdfFile.path, type, id, cancelToken, onReceiverProgress);
      // }
      if (pdfFile.lengthSync() == 0) return null;
      return pdfFile;
    }
    return null;
  }

  static Future<File> getExcelTemplate(
      {String fileName = "contacts",
      CancelToken cancelToken,
      ProgressCallback onReceiverProgress}) async {
    if (await PermissionManager().canWriteStorage()) {
      var directory;
      if (Platform.isIOS) {
        directory = await pathProvider.getApplicationDocumentsDirectory();
      } else if (Platform.isAndroid) {
        // directory = await pathProvider.getExternalStorageDirectory();
        directory = Directory('/storage/emulated/0/Download');
        // Put file in global download folder, if for an unknown reason it didn't exist, we fallback
        // ignore: avoid_slow_async_io
        if (!await directory.exists())
          directory = await pathProvider.getExternalStorageDirectory();
      }
      // Directory excelDir = Directory(path.join(directory.path, 'excel'));
      // if (!excelDir.existsSync()) {
      //   await excelDir.create();
      // }
      String excelFileName =
          path.setExtension(path.join(directory.path, fileName), '.xlsx');
      logger.d("下载的路径 = $excelFileName");
      File excelFile = File(excelFileName);
      if (excelFile.existsSync()) await excelFile.delete();
      return await excelFile.create();
    }
    return null;
  }

  /// 下载Excel模板文件
  static Future<Response> downloadExcelTemplate(String filePath,
      {CancelToken cancelToken,
      ProgressCallback onReceiveProgress,
      int current}) {
    Future<Response> future;
    switch (current) {
      case 0:
        future = BaseConfig.httpBase.download('/api/contacts/excel', filePath,
            {}, cancelToken, onReceiveProgress);
        break;
      case 1:
        future = BaseConfig.httpBase.download('/api/init/bill_invoice/excel',
            filePath, {}, cancelToken, onReceiveProgress);
        break;
      case 2:
        future = BaseConfig.httpBase.download('/api/init/product_service/excel',
            filePath, {}, cancelToken, onReceiveProgress);
        break;
      case 3:
        future = BaseConfig.httpBase.download(
            '/api/coa/download', filePath, {}, cancelToken, onReceiveProgress);
        break;
    }
    return future;
  }

  static Future<File> getSOAPdfFile(
      String type, int id, String payment, String note,
      {CancelToken cancelToken, ProgressCallback onReceiverProgress}) async {
    if (await PermissionManager().canWriteStorage()) {
      File pdfFile = File(await getPdfFilePath(type, id));
      // if (!pdfFile.existsSync() || pdfFile.lengthSync() == 0) {
      if (pdfFile.existsSync()) {
        await pdfFile.delete();
      }
      await pdfFile.create();
      await HttpStatementOfAccountService.downloadSOA(
          pdfFile.path, id, payment, note, cancelToken, onReceiverProgress);
      // }
      if (pdfFile.lengthSync() == 0) return null;
      return pdfFile;
    }
    return null;
  }

  static Future<String> getPdfFilePath(String type, int id) async {
    final directory = await pathProvider.getApplicationDocumentsDirectory();
    Directory pdfDir = Directory(path.join(directory.path, 'pdf'));
    if (!pdfDir.existsSync()) {
      await pdfDir.create();
    }
    String urlLink = HttpCommonService.downloadPDFUrl(type, id);
    String md5PdfFilename =
        hex.encode(md5.convert(Utf8Encoder().convert(urlLink)).bytes);
    md5PdfFilename =
        path.setExtension(path.join(pdfDir.path, md5PdfFilename), '.pdf');

    return md5PdfFilename;
  }

  static Future<String> _getFilePathByUrl(
      Response<dynamic> result, String fileType) async {
    final directory = await pathProvider.getApplicationDocumentsDirectory();
    Directory pdfDir = Directory(path.join(directory.path, fileType));
    if (!pdfDir.existsSync()) {
      await pdfDir.create();
    }
    String urlLink = result.requestOptions.uri.toString();
    print(urlLink);
    String md5PdfFilename =
        hex.encode(md5.convert(Utf8Encoder().convert(urlLink)).bytes);
    md5PdfFilename =
        path.setExtension(path.join(pdfDir.path, md5PdfFilename), '.$fileType');

    return md5PdfFilename;
  }

  static Future<String> getAudioFile(String fileName) async {
    if (await PermissionManager().canWriteStorage()) {
      final directory = await pathProvider.getApplicationDocumentsDirectory();
      Directory audioDir = Directory(path.join(directory.path, 'audio'));
      if (!audioDir.existsSync()) {
        await audioDir.create();
      }
      File audioFile = File(path.join(audioDir.path, fileName));
      if (await audioFile.exists()) {
        print('删除音频文件');
        await audioFile.delete(recursive: true);
      }
      // await audioFile.create();
      return audioFile.path;
    }
    return null;
  }

  static void openFile(File file) async {
    OpenFile.open(file.path);
    // await launch(Uri.dataFromString(file.reas,
    //     encoding: utf8, mimeType: 'application/pdf').toString());
  }
}
